home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 9305 < prev    next >
Encoding:
Text File  |  1996-08-05  |  5.3 KB  |  174 lines

  1. Path: keats.ugrad.cs.ubc.ca!not-for-mail
  2. From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: suspicious pointer conversion warning
  5. Date: 8 Mar 1996 15:26:47 -0800
  6. Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
  7. Message-ID: <4hqfnnINNakc@keats.ugrad.cs.ubc.ca>
  8. References: <4hpmgt$4uu@muss.CIS.McMaster.CA>
  9. NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
  10.  
  11. In article <4hpmgt$4uu@muss.CIS.McMaster.CA>,
  12. S. Jon <u9010255@muss.cis.McMaster.CA> wrote:
  13.  >to all the pointer gods out there:
  14.  >
  15.  >i cannot figure out what's wrong with my program.  i always get a 
  16.  >suspicious pointer conversion warning when i try to reallocate more memory.
  17.  >
  18.  >the purpose of my program is to open a text file and put all the words 
  19.  >into an array.  i initially set my array for 20 words and if there is 
  20.  >more than 20 words, i increase the array with a growth factor of 10 by 
  21.  >using realloc.
  22.  >
  23.  >i would appreciate any input from anyone.  pointers and i just don't 
  24.  >mix!  i can't wait 'til i try linked lists!!!! :)
  25.  >
  26.  >my program is divided into 3 files: wcount.h, wcount.c (main source file), 
  27.  >wcount2.c (all my functions).  compiler is borland c++ v3.1 for dos. here is 
  28.  >selected parts of my program that i think are relevant:
  29.  >
  30.  >--------------------------------------------
  31.  >//    FILENAME: wcount.h
  32.  
  33. This is a syntax error. The ISO standard does not define any meaning for a
  34. combination of the // characters outside of a string literal.
  35.  
  36. Don't mix C++ features into C code.
  37.  
  38.  >#ifndef WCOUNT_H
  39.  >#define WCOUNT_H
  40.  >
  41.  >typedef struct
  42.  >{
  43.  >  int    iFrequency;
  44.  >  char    szWord[1];   // variable length array
  45.  >}  WordInfo;
  46.  
  47. There is no such thing as variable length arrays in C. The above is an array of
  48. one character.  Your mastery of C is somewhat lagging behind your enthusiasm to
  49. use what seems to be a variant of Hungarian notation. :)
  50.  
  51.  >//  FILENAME wcount.c
  52.  
  53. Where is the inclusion of "wcount.h"?
  54.  
  55.  >int main ()
  56.  >{
  57.  >  int       iWordCount;
  58.  >  WordInfo  *apWords[20];  // array of pointers to structure WordInfo
  59.  >  FILE      *fpFile;
  60.  >
  61.  >//  program opens file
  62.  >
  63.  >  iWordCount = Parse (fpFile, apWords);
  64.  >
  65.  >//  program displays the words
  66.  >
  67.  >  return (0);
  68.  >}
  69.  >
  70.  >----------------------------------------
  71.  >
  72.  >//  FILENAME wcount2.c
  73.  
  74. Where is the inclusion of wcount.h? You are using data types here that were
  75. declared in there.
  76.  
  77.  >int Parse (FILE *fpFile, WordInfo *apWords[])
  78.  >{
  79.  >  int    iWordLimit = 20;  // initially limited to 20 words
  80.  
  81. Why are you using the magic number 20 here and in main()? How does this
  82. function know that apWords is an array of 20 pointers? At least it could be a
  83. global variable or pre-processor constant.
  84.  
  85.  >  int    iWordCount;   // running count on the number of words in array
  86.  >
  87.  >//    program parses words here and puts word in array with malloc
  88.  >//    program also compares any new word with words in array to avoid 
  89.  >//    duplication
  90.  
  91.  
  92. You did not initialize iWordCount (boy, that's hard to read and type!). Its
  93. value is undefined here.
  94.  
  95.  >  if (iWordCount == iWordLimit)
  96.  >  {
  97.  >    iWordLimit += 10;
  98.  
  99. At this point you have not read anything from a data file, so why perform a
  100. check? Just grab the memory. You are using an unitialized variable, hence
  101. calling for behavior that is undefined. Doesn't your compiler produce a
  102. diagnostic?
  103.  
  104.  >//  ***** SUSPICIOUS POINTER ERROR REFERS TO LINE BELOW
  105.  >
  106.  >    apWords = GetMoreMem (apWords, iWordLimit);
  107.  
  108. You cannot reallocate apWords! The pointer you are trying to reallocate was not
  109. created with malloc(). It is the pointer to  the first element of an array
  110. declared as an automatic variable inside main().
  111.  
  112. This is completely wrong.
  113.  
  114. My recommendations: 
  115.  
  116. 1.     change the apWords array declaration in main() into a
  117.     pointer rather than an array.
  118.  
  119. 3.    Inside Parse, explicitly malloc() 20 (or however many) pointers, then
  120.     realloc in the given increment when you fill up that limit.
  121.  
  122. 4.    Produce the final array of pointers as a return value.
  123.  
  124. 5.    Return the size by passing the address of an integer into Parse.
  125.  
  126. Then, inside main() you could write:
  127.  
  128.     int iWordCount;
  129.     WordInfo **apWords = Parse(fpFile, &iWordCount);
  130.  
  131. and in Parse() you have something like:
  132.  
  133. WordInfo **Parse(FILE *fpFile, int *size)
  134. {
  135.     int arraysize = BASE_SIZE;    /* allocated array size    */
  136.     int datasize = 0;        /* actual size        */
  137.  
  138.     Wordinfo **words = GetMoreMem(0, BASE_SIZE);    /* see recommendation 
  139.                                below */
  140.  
  141.     /* scan the file, reallocating ``words'' as needed */
  142.  
  143.     *size = datasize;
  144.     return words;
  145. }
  146.  
  147.  >WordInfo *GetMoreMem (const WordInfo *apWords[], int iWordLimit)
  148.  >{
  149.  >  WordInfo *pTemp;    // temp pointer to struct WordInfo
  150.  >
  151.  >  pTemp = (WordInfo *)realloc(apWords, iWordLimit*sizeof(WordInfo));
  152.  
  153. This is wrong. You want to allocate a block of pointers. Here you are
  154. allocating a block of WordInfo structures, and assigning it to a pointer to a
  155. WordInfo structure. The corrected code should read:
  156.  
  157.     WordInfo **pTemp = realloc(apWords, iWordLimit*sizeof(WordInfo *));
  158.  
  159.  
  160.  >  if (pTemp == NULL)
  161.  >  {
  162.  >    exit (EXIT_FAILURE);
  163.  >  }
  164.  >  return (pTemp);
  165.  >}
  166.  
  167. Why don't you check for a null input value for apWords here? If it is null, you
  168. can malloc() a fresh new array. If not, realloc() the existing one. This way,
  169. you can use GetMoreMem() to create the initial array of 20 blocks by starting
  170. with a null pointer (as I did above), and can use the same function to increase
  171. the size later.  
  172. -- 
  173.  
  174.